Description

Objects that are used in this notebook are generated with 01-Exploratory_analysis_and_differential_expression nb and loaded with RDS. Here we connect mRNA - mir and mRNA - DNAm data. We are exploring do miR and DNAm regulate the the expression of mRNA to do so we need to identify the targets of those kinds of regulations. For miR targets we query the database of mir-gene inrerctions mirTarBase that have experimentally supported evidence. DNAm targets are determined as differentially methylated cpg islands in promoter regions of genes. For this analysiso only significant results with adjsuted p-values < 0.05 are considered.

Libraries

library(multiMiR)
library(gprofiler2)
library(knitr)
library(dplyr)

Loading data

rprojroot::find_root()
Error in as_root_criterion(criterion) : 
  argument "criterion" is missing, with no default

Check if colnames mRNA dds is not null

if(colnames(mRNA_dds)%>%is.null()){
  colnames(mRNA_dds) <- colData(mRNA_dds)$GRCE.NAME
}

miR - mRNA

##Interactions

Interaction tables are obtained by querying with multimir package. Setting up the query.

# Significant mir's
mir_query <- rownames(dplyr::filter(as.data.frame(mir_res), padj < 0.05))

# Significant mRNA
mRNA_query <- rownames(dplyr::filter(as.data.frame(mRNA_res), padj < 0.05))

print(paste("Length of mir query: ", length(mir_query),
             "   Length of mRNA query: ", length(mRNA_query)))
[1] "Length of mir query:  514    Length of mRNA query:  2993"

Querying the database

database <- "mirtarbase"

# Querying
multi_db <- get_multimir(mirna = mir_query,
                         target = mRNA_query,
                         table = database)
Searching mirtarbase ...
# Selecting results
targ_mir_mRNA <- 
  multiMiR::select(multi_db,
                   keytype = "type",
                   keys = "validated",
                   columns = c("mature_mirna_id", 
                               "target_ensembl",
                               "target_symbol"))

# Removing duplicates and removing type column (redundant)
targ_mir_mRNA <- unique(dplyr::select(targ_mir_mRNA, -type))

rm(multi_db)

head(targ_mir_mRNA)
NA
NA
print(c(paste("Number of mRNA mir interactions: ", dim(targ_mir_mRNA)[1]),
        paste("Number of mirs in interactions: ",
              length(unique(targ_mir_mRNA$mature_mirna_id))),
        paste("Number of target genes :", 
              length(unique(targ_mir_mRNA$target_ensembl)))))
[1] "Number of mRNA mir interactions:  2619" "Number of mirs in interactions:  90"   
[3] "Number of target genes : 1088"         
# Frequency table of mir's in the interaction table
table(targ_mir_mRNA$mature_mirna_id) %>%
  as.data.frame() %>%
  arrange(desc(Freq)) %>%
  head()
# Frequency of genes in interaction table
head(table(targ_mir_mRNA$target_symbol) %>%
  as.data.frame() %>%
  arrange(desc(Freq)))

GSEA analysis on genes under mir regulation. Around half of DE genes are targets for mir regulation. Terms that appear in GSEA analysis are involved in regulation of cellular processes, regulation of transcription, there is a KEGG term proteoglyncans in cancer, and several REACTOME terms involved in cell cycle regulation.

# Using only part of sources
GSEA_SOURCES <- c("GO:BP","CORUM","KEGG","REAC","WP","MIRNA", "TF")

# Calling gost function
gost_res <- 
    gost(targ_mir_mRNA$target_ensembl,
       organism= "hsapiens",
       exclude_iea=TRUE,
       domain_scope="annotated",
       ordered_query=F,
       sources=GSEA_SOURCES)

# Change query name
gost_res$result$query <- "Mir targets on whole genome background"

gostplot(gost_res, capped = FALSE)

HPV Effect

Querying the database for mirs and mRNA that are DE in the HPV group.

Building queries

# building mir query
mir_HPV_query <- filter(as.data.frame(mir_res_HPV), pvalue < 0.05)$row

# building mRNA query
mRNA_HPV_query <- filter(as.data.frame(mRNA_res_HPV), pvalue < 0.05)$row

print(paste("Length of mir query: ", length(mir_HPV_query),
             "   Length of mRNA query: ", length(mRNA_HPV_query)))
[1] "Length of mir query:  20    Length of mRNA query:  39"
# Frequency table of mir's in the interaction table
table(targ_mir_mRNA_HPV$mature_mirna_id) %>%
  as.data.frame()%>%
  arrange(desc(Freq))

# Frequency of genes in interaction table
table(targ_mir_mRNA_HPV$target_symbol) %>%
  as.data.frame()%>%
  arrange(desc(Freq))
# Calling gost function
gost_res <- 
    gost(targ_mir_mRNA_HPV$target_ensembl,
       organism= "hsapiens",
       exclude_iea=TRUE,
       domain_scope="annotated",
       ordered_query=F,
       sources=GSEA_SOURCES)
No results to show
Please make sure that the organism is correct or set significant = FALSE

Correlation

Testing count correlation for mir and mRNA for interaction pairs. Input are normalized count data for the 13 intersecting samples. This table will be used for picking the best mir to attach in the integrative table.

# Data frame with correlations
cor_mir <- 
  dplyr::select(targ_mir_mRNA,
                mir = mature_mirna_id,
                symbol = target_symbol,
                gene = target_ensembl)


# Looping through all the pairs.
for(i in 1:dim(cor_mir)[1]){
  if(i%%100 ==0){
    message(paste("Processing pair number: ",i,
                  " mir: ",cor_mir$mir[i],
                  " gene ",  cor_mir$symbol[i]))
  }
  c <- 
    cor.test(x=as.numeric(
      counts(mir_dds, normalize=TRUE)[cor_mir$mir[i],colnames(mRNA_dds)]),
      y=as.numeric(
        counts(mRNA_dds, normalize=TRUE)[cor_mir$gene[i],]),
      method="spearman",
      exact = FALSE)
  cor_mir$r[i] <- c$estimate
  cor_mir$pvalue[i] <- c$p.value
}

# Saving cor_mir object into RDS because of long computing time
saveRDS(cor_mir, "outputs/RDS/cor_mir.rds")
# best correlations
cor_mir <- readRDS("outputs/RDS/cor_mir.rds")
head(dplyr::arrange(cor_mir,r))
tail(dplyr::arrange(cor_mir,r))

DNAm - mRNA

Creating an DNA methylation and mRNA table. As input for DNAm a granges object with cpg island intervals and a column that contains gene names whose promoter region overlaps that cpg island.

targ_dnam_mRNA <- saveRDS("outputs/RDS/targ_dnam_mRNA.rds")
Error in saveRDS("outputs/RDS/targ_dnam_mRNA.rds") : 
  'file' must be non-empty string

Some of the cpg (19) islands overlap more than one gene promoter, and 72 genes have 2 (exactly) cpg islands in their promoters.

GSEA GSEA analysis on genes that are under methylation regulation. There many terms from TF source which is expected. Since the differentially methylated cpg islands that were selected are in promoter regions of those genes. Also in from the reactom database there are many terms involved in the regulation of the cell cycle.

# Using only part of sources
GSEA_SOURCES <- c("GO:BP","CORUM","KEGG","REAC","WP","MIRNA", "TF")

# Calling gost function
gost_res <- 
    gost(targ_dnam_mRNA$ensembl,
       organism= "hsapiens",
       exclude_iea=TRUE,
       domain_scope="annotated",
       ordered_query=F,
       sources=GSEA_SOURCES)

# Change query name
gost_res$result$query <- "DE genes with DM promoters"

gostplot(gost_res, capped = FALSE)

Session Info

sessionInfo()
LS0tCnRpdGxlOiAiMDIgUmVndWxhdGlvbiB0YXJnZXRzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIERlc2NyaXB0aW9uCk9iamVjdHMgdGhhdCBhcmUgdXNlZCBpbiB0aGlzIG5vdGVib29rIGFyZSBnZW5lcmF0ZWQgd2l0aCAwMS1FeHBsb3JhdG9yeV9hbmFseXNpc19hbmRfZGlmZmVyZW50aWFsX2V4cHJlc3Npb24gbmIgYW5kIGxvYWRlZCB3aXRoIFJEUy4gSGVyZSB3ZSBjb25uZWN0IG1STkEgLSBtaXIgYW5kIG1STkEgLSBETkFtIGRhdGEuIFdlIGFyZSBleHBsb3JpbmcgZG8gbWlSIGFuZCBETkFtIHJlZ3VsYXRlIHRoZSB0aGUgZXhwcmVzc2lvbiBvZiBtUk5BIHRvIGRvIHNvIHdlIG5lZWQgdG8gaWRlbnRpZnkgdGhlIHRhcmdldHMgb2YgdGhvc2Uga2luZHMgb2YgcmVndWxhdGlvbnMuCkZvciBtaVIgdGFyZ2V0cyB3ZSBxdWVyeSB0aGUgZGF0YWJhc2Ugb2YgbWlyLWdlbmUgaW5yZXJjdGlvbnMgbWlyVGFyQmFzZSB0aGF0IGhhdmUgZXhwZXJpbWVudGFsbHkgc3VwcG9ydGVkIGV2aWRlbmNlLiBETkFtIHRhcmdldHMgYXJlIGRldGVybWluZWQgYXMgZGlmZmVyZW50aWFsbHkgbWV0aHlsYXRlZCBjcGcgaXNsYW5kcyBpbiBwcm9tb3RlciByZWdpb25zIG9mIGdlbmVzLiBGb3IgdGhpcyBhbmFseXNpc28gb25seSBzaWduaWZpY2FudCByZXN1bHRzIHdpdGggYWRqc3V0ZWQgcC12YWx1ZXMgPCAwLjA1IGFyZSBjb25zaWRlcmVkLgoKIyBMaWJyYXJpZXMKYGBge3IgTGlicmFyaWVzLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KG11bHRpTWlSKQpsaWJyYXJ5KGdwcm9maWxlcjIpCmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoZHBseXIpCmBgYAoKIyBMb2FkaW5nIGRhdGEKYGBge3J9CiMgRGVzdGluYXRpb24gb2Ygb3V0cHV0cyBmcm9tIDAxLUV4cGxvcmF0b3J5X2FuYWx5c2lzX2FuZF9kaWZmX2V4cHJlc3Npb24gCmRpcl9kZXN0IDwtICIvaG9tZS9rYXRhcmluYS9NeVByb2plY3RzL0hOU0NDLzAxLUV4cGxvcmF0b3J5X2FuYWx5c2lzX2FuZF9kaWZmZXJlbnRpYWxfZXhwcmVzc2lvbi9vdXRwdXRzL1JEUyIKCgojIG1STkEKbVJOQV9kZHMgPC0gcmVhZFJEUyhmaWxlLnBhdGgoZGlyX2Rlc3QsICJtUk5BX2Rkcy5yZHMiKSkKbVJOQV9kZHNfSFBWIDwtIHJlYWRSRFMoZmlsZS5wYXRoKGRpcl9kZXN0LCAibVJOQV9kZHNfSFBWLnJkcyIpKQptUk5BX3JlcyA8LSByZWFkUkRTKGZpbGUucGF0aChkaXJfZGVzdCwgIm1STkFfcmVzLnJkcyIpKQptUk5BX3Jlc19IUFYgPC0gcmVhZFJEUyhmaWxlLnBhdGgoZGlyX2Rlc3QsICJtUk5BX3Jlc19IUFYucmRzIikpCgoKIyBtaXIKbWlyX2RkcyA8LSByZWFkUkRTKGZpbGUucGF0aChkaXJfZGVzdCwgIm1pcl9kZHMucmRzIikpCm1pcl9kZHNfSFBWIDwtIHJlYWRSRFMoZmlsZS5wYXRoKGRpcl9kZXN0LCAibWlyX2Rkc19IUFYucmRzIikpCm1pcl9yZXMgPC0gcmVhZFJEUyhmaWxlLnBhdGgoZGlyX2Rlc3QsICJtaXJfcmVzLnJkcyIpKQptaXJfcmVzX0hQViA8LSByZWFkUkRTKGZpbGUucGF0aChkaXJfZGVzdCwgIm1pcl9yZXNfSFBWLnJkcyIpKQoKIyBETkFtCnJuYl9zZXQgPC0gcmVhZFJEUyhmaWxlLnBhdGgoZGlyX2Rlc3QsICJybmJfc2V0LnJkcyIpKQpkbmFtX3Jlc19jZ2kgPC0gcmVhZFJEUyhmaWxlLnBhdGgoZGlyX2Rlc3QsICJkbmFtX3Jlc19jZ2kucmRzIikpCmBgYApDaGVjayBpZiBjb2xuYW1lcyBtUk5BIGRkcyBpcyBub3QgbnVsbCAKYGBge3J9CmlmKGNvbG5hbWVzKG1STkFfZGRzKSU+JWlzLm51bGwoKSl7CiAgY29sbmFtZXMobVJOQV9kZHMpIDwtIGNvbERhdGEobVJOQV9kZHMpJEdSQ0UuTkFNRQp9CmBgYAoKCiMgbWlSIC0gbVJOQQojI0ludGVyYWN0aW9ucwoKSW50ZXJhY3Rpb24gdGFibGVzIGFyZSBvYnRhaW5lZCBieSBxdWVyeWluZyB3aXRoIG11bHRpbWlyIHBhY2thZ2UuIFNldHRpbmcgdXAgdGhlIHF1ZXJ5LgpgYGB7cn0KIyBTaWduaWZpY2FudCBtaXIncwptaXJfcXVlcnkgPC0gcm93bmFtZXMoZHBseXI6OmZpbHRlcihhcy5kYXRhLmZyYW1lKG1pcl9yZXMpLCBwYWRqIDwgMC4wNSkpCgojIFNpZ25pZmljYW50IG1STkEKbVJOQV9xdWVyeSA8LSByb3duYW1lcyhkcGx5cjo6ZmlsdGVyKGFzLmRhdGEuZnJhbWUobVJOQV9yZXMpLCBwYWRqIDwgMC4wNSkpCgpwcmludChwYXN0ZSgiTGVuZ3RoIG9mIG1pciBxdWVyeTogIiwgbGVuZ3RoKG1pcl9xdWVyeSksCiAgICAgICAgICAgICAiICAgTGVuZ3RoIG9mIG1STkEgcXVlcnk6ICIsIGxlbmd0aChtUk5BX3F1ZXJ5KSkpCmBgYApRdWVyeWluZyB0aGUgZGF0YWJhc2UKCmBgYHtyfQpkYXRhYmFzZSA8LSAibWlydGFyYmFzZSIKCiMgUXVlcnlpbmcKbXVsdGlfZGIgPC0gZ2V0X211bHRpbWlyKG1pcm5hID0gbWlyX3F1ZXJ5LAogICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0ID0gbVJOQV9xdWVyeSwKICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlID0gZGF0YWJhc2UpCgojIFNlbGVjdGluZyByZXN1bHRzCnRhcmdfbWlyX21STkEgPC0gCiAgbXVsdGlNaVI6OnNlbGVjdChtdWx0aV9kYiwKICAgICAgICAgICAgICAgICAgIGtleXR5cGUgPSAidHlwZSIsCiAgICAgICAgICAgICAgICAgICBrZXlzID0gInZhbGlkYXRlZCIsCiAgICAgICAgICAgICAgICAgICBjb2x1bW5zID0gYygibWF0dXJlX21pcm5hX2lkIiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidGFyZ2V0X2Vuc2VtYmwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldF9zeW1ib2wiKSkKCiMgUmVtb3ZpbmcgZHVwbGljYXRlcyBhbmQgcmVtb3ZpbmcgdHlwZSBjb2x1bW4gKHJlZHVuZGFudCkKdGFyZ19taXJfbVJOQSA8LSB1bmlxdWUoZHBseXI6OnNlbGVjdCh0YXJnX21pcl9tUk5BLCAtdHlwZSkpCgpybShtdWx0aV9kYikKCmhlYWQodGFyZ19taXJfbVJOQSkKCnNhdmVSRFModGFyZ19taXJfbVJOQSwgIm91dHB1dHMvUkRTL3RhcmdfbWlyX21STkEucmRzIikKCmBgYAoKYGBge3J9CnByaW50KGMocGFzdGUoIk51bWJlciBvZiBtUk5BIG1pciBpbnRlcmFjdGlvbnM6ICIsIGRpbSh0YXJnX21pcl9tUk5BKVsxXSksCiAgICAgICAgcGFzdGUoIk51bWJlciBvZiBtaXJzIGluIGludGVyYWN0aW9uczogIiwKICAgICAgICAgICAgICBsZW5ndGgodW5pcXVlKHRhcmdfbWlyX21STkEkbWF0dXJlX21pcm5hX2lkKSkpLAogICAgICAgIHBhc3RlKCJOdW1iZXIgb2YgdGFyZ2V0IGdlbmVzIDoiLCAKICAgICAgICAgICAgICBsZW5ndGgodW5pcXVlKHRhcmdfbWlyX21STkEkdGFyZ2V0X2Vuc2VtYmwpKSkpKQpgYGAKYGBge3J9CiMgRnJlcXVlbmN5IHRhYmxlIG9mIG1pcidzIGluIHRoZSBpbnRlcmFjdGlvbiB0YWJsZQp0YWJsZSh0YXJnX21pcl9tUk5BJG1hdHVyZV9taXJuYV9pZCkgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIGFycmFuZ2UoZGVzYyhGcmVxKSkgJT4lCiAgaGVhZCgpCmBgYAoKYGBge3J9CiMgRnJlcXVlbmN5IG9mIGdlbmVzIGluIGludGVyYWN0aW9uIHRhYmxlCmhlYWQodGFibGUodGFyZ19taXJfbVJOQSR0YXJnZXRfc3ltYm9sKSAlPiUKICBhcy5kYXRhLmZyYW1lKCkgJT4lCiAgYXJyYW5nZShkZXNjKEZyZXEpKSkKYGBgCgpHU0VBIGFuYWx5c2lzIG9uIGdlbmVzIHVuZGVyIG1pciByZWd1bGF0aW9uLiBBcm91bmQgaGFsZiBvZiBERSBnZW5lcyBhcmUgdGFyZ2V0cyBmb3IgbWlyIHJlZ3VsYXRpb24uIFRlcm1zIHRoYXQgYXBwZWFyIGluIEdTRUEgYW5hbHlzaXMgYXJlIGludm9sdmVkIGluIHJlZ3VsYXRpb24gb2YgY2VsbHVsYXIgcHJvY2Vzc2VzLCByZWd1bGF0aW9uIG9mIHRyYW5zY3JpcHRpb24sIHRoZXJlIGlzIGEgS0VHRyB0ZXJtIHByb3Rlb2dseW5jYW5zIGluIGNhbmNlciwgYW5kIHNldmVyYWwgUkVBQ1RPTUUgdGVybXMgaW52b2x2ZWQgaW4gY2VsbCBjeWNsZSByZWd1bGF0aW9uLgpgYGB7cn0KIyBVc2luZyBvbmx5IHBhcnQgb2Ygc291cmNlcwpHU0VBX1NPVVJDRVMgPC0gYygiR086QlAiLCJDT1JVTSIsIktFR0ciLCJSRUFDIiwiV1AiLCJNSVJOQSIsICJURiIpCgojIENhbGxpbmcgZ29zdCBmdW5jdGlvbgpnb3N0X3JlcyA8LSAKICAgIGdvc3QodGFyZ19taXJfbVJOQSR0YXJnZXRfZW5zZW1ibCwKICAgICAgIG9yZ2FuaXNtPSAiaHNhcGllbnMiLAogICAgICAgZXhjbHVkZV9pZWE9VFJVRSwKICAgICAgIGRvbWFpbl9zY29wZT0iYW5ub3RhdGVkIiwKICAgICAgIG9yZGVyZWRfcXVlcnk9RiwKICAgICAgIHNvdXJjZXM9R1NFQV9TT1VSQ0VTKQoKIyBDaGFuZ2UgcXVlcnkgbmFtZQpnb3N0X3JlcyRyZXN1bHQkcXVlcnkgPC0gIk1pciB0YXJnZXRzIG9uIHdob2xlIGdlbm9tZSBiYWNrZ3JvdW5kIgoKZ29zdHBsb3QoZ29zdF9yZXMsIGNhcHBlZCA9IEZBTFNFKQpgYGAKCiMjIEhQViBFZmZlY3QKUXVlcnlpbmcgdGhlIGRhdGFiYXNlIGZvciBtaXJzIGFuZCBtUk5BIHRoYXQgYXJlIERFIGluIHRoZSBIUFYgZ3JvdXAuCgpCdWlsZGluZyBxdWVyaWVzCmBgYHtyfQojIGJ1aWxkaW5nIG1pciBxdWVyeQptaXJfSFBWX3F1ZXJ5IDwtIGZpbHRlcihhcy5kYXRhLmZyYW1lKG1pcl9yZXNfSFBWKSwgcHZhbHVlIDwgMC4wNSkkcm93CgojIGJ1aWxkaW5nIG1STkEgcXVlcnkKbVJOQV9IUFZfcXVlcnkgPC0gZmlsdGVyKGFzLmRhdGEuZnJhbWUobVJOQV9yZXNfSFBWKSwgcHZhbHVlIDwgMC4wNSkkcm93CgpwcmludChwYXN0ZSgiTGVuZ3RoIG9mIG1pciBxdWVyeTogIiwgbGVuZ3RoKG1pcl9IUFZfcXVlcnkpLAogICAgICAgICAgICAgIiAgIExlbmd0aCBvZiBtUk5BIHF1ZXJ5OiAiLCBsZW5ndGgobVJOQV9IUFZfcXVlcnkpKSkKYGBgCgpgYGB7cn0KIyBxdWVyeWluZyBhbGwgZGF0YWJhc2VzIHRoYXQgY29udGFpbiBwcmVkaWN0ZWQgaW50ZXJhY3Rpb25zCm11bHRpX2RiIDwtIGdldF9tdWx0aW1pcihtaXJuYSA9IG1pcl9IUFZfcXVlcnksCiAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXQgPSBtUk5BX0hQVl9xdWVyeSwKICAgICAgICAgICAgICAgICAgICAgICAgIHRhYmxlID0gInByZWRpY3RlZCIpCgojIFNlbGVjdGluZyBjb2x1bW5zCnRhcmdfbWlyX21STkFfSFBWIDwtIAogIG11bHRpTWlSOjpzZWxlY3QobXVsdGlfZGIsCiAgICAgICAgICAgICAgICAgICBrZXl0eXBlID0gInR5cGUiLAogICAgICAgICAgICAgICAgICAga2V5cyA9ICJwcmVkaWN0ZWQiLAogICAgICAgICAgICAgICAgICAgY29sdW1ucyA9IGMoIm1hdHVyZV9taXJuYV9pZCIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInRhcmdldF9lbnNlbWJsIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0YXJnZXRfc3ltYm9sIikpCgojIFNlbGVjdGluZyBvbmx5IHVuaXF1ZSBpbnRlcmFjdGlvbiwgZHJvcHBpbmcgdHlwZQp0YXJnX21pcl9tUk5BX0hQViA8LXVuaXF1ZShkcGx5cjo6c2VsZWN0KHRhcmdfbWlyX21STkFfSFBWLCAtdHlwZSkpCgp0YXJnX21pcl9tUk5BX0hQVgpgYGAKYGBge3J9CiMgRnJlcXVlbmN5IHRhYmxlIG9mIG1pcidzIGluIHRoZSBpbnRlcmFjdGlvbiB0YWJsZQp0YWJsZSh0YXJnX21pcl9tUk5BX0hQViRtYXR1cmVfbWlybmFfaWQpICU+JQogIGFzLmRhdGEuZnJhbWUoKSU+JQogIGFycmFuZ2UoZGVzYyhGcmVxKSkKCiMgRnJlcXVlbmN5IG9mIGdlbmVzIGluIGludGVyYWN0aW9uIHRhYmxlCnRhYmxlKHRhcmdfbWlyX21STkFfSFBWJHRhcmdldF9zeW1ib2wpICU+JQogIGFzLmRhdGEuZnJhbWUoKSU+JQogIGFycmFuZ2UoZGVzYyhGcmVxKSkKYGBgCgpgYGB7cn0KIyBVc2luZyBvbmx5IHBhcnQgb2Ygc291cmNlcwpHU0VBX1NPVVJDRVMgPC0gYygiR086QlAiLCJDT1JVTSIsIktFR0ciLCJSRUFDIiwiV1AiLCJNSVJOQSIsICJURiIpCgojIENhbGxpbmcgZ29zdCBmdW5jdGlvbgpnb3N0X3JlcyA8LSAKICAgIGdvc3QodGFyZ19taXJfbVJOQV9IUFYkdGFyZ2V0X2Vuc2VtYmwsCiAgICAgICBvcmdhbmlzbT0gImhzYXBpZW5zIiwKICAgICAgIGV4Y2x1ZGVfaWVhPVRSVUUsCiAgICAgICBkb21haW5fc2NvcGU9ImFubm90YXRlZCIsCiAgICAgICBvcmRlcmVkX3F1ZXJ5PUYsCiAgICAgICBzb3VyY2VzPUdTRUFfU09VUkNFUykKCiMgQ2hhbmdlIHF1ZXJ5IG5hbWUKZ29zdF9yZXMkcmVzdWx0JHF1ZXJ5IDwtICJNaXIgSFBWIHRhcmdldHMgb24gd2hvbGUgZ2Vub21lIGJhY2tncm91bmQiCgpnb3N0cGxvdChnb3N0X3JlcywgY2FwcGVkID0gRkFMU0UpCmBgYAojIyBDb3JyZWxhdGlvbgoKVGVzdGluZyBjb3VudCBjb3JyZWxhdGlvbiBmb3IgbWlyIGFuZCBtUk5BIGZvciBpbnRlcmFjdGlvbiBwYWlycy4gSW5wdXQgYXJlIG5vcm1hbGl6ZWQgY291bnQgZGF0YSBmb3IgdGhlIDEzIGludGVyc2VjdGluZyBzYW1wbGVzLiBUaGlzIHRhYmxlIHdpbGwgYmUgdXNlZCBmb3IgcGlja2luZyB0aGUgYmVzdCBtaXIgdG8gYXR0YWNoIGluIHRoZSBpbnRlZ3JhdGl2ZSB0YWJsZS4KCmBgYHtyLCBldmFsPUZBTFNFfQojIERhdGEgZnJhbWUgd2l0aCBjb3JyZWxhdGlvbnMKY29yX21pciA8LSAKICBkcGx5cjo6c2VsZWN0KHRhcmdfbWlyX21STkEsCiAgICAgICAgICAgICAgICBtaXIgPSBtYXR1cmVfbWlybmFfaWQsCiAgICAgICAgICAgICAgICBzeW1ib2wgPSB0YXJnZXRfc3ltYm9sLAogICAgICAgICAgICAgICAgZ2VuZSA9IHRhcmdldF9lbnNlbWJsKQoKCiMgTG9vcGluZyB0aHJvdWdoIGFsbCB0aGUgcGFpcnMuCmZvcihpIGluIDE6ZGltKGNvcl9taXIpWzFdKXsKICBpZihpJSUxMDAgPT0wKXsKICAgIG1lc3NhZ2UocGFzdGUoIlByb2Nlc3NpbmcgcGFpciBudW1iZXI6ICIsaSwKICAgICAgICAgICAgICAgICAgIiBtaXI6ICIsY29yX21pciRtaXJbaV0sCiAgICAgICAgICAgICAgICAgICIgZ2VuZSAiLCAgY29yX21pciRzeW1ib2xbaV0pKQogIH0KICBjIDwtIAogICAgY29yLnRlc3QoeD1hcy5udW1lcmljKAogICAgICBjb3VudHMobWlyX2Rkcywgbm9ybWFsaXplPVRSVUUpW2Nvcl9taXIkbWlyW2ldLGNvbG5hbWVzKG1STkFfZGRzKV0pLAogICAgICB5PWFzLm51bWVyaWMoCiAgICAgICAgY291bnRzKG1STkFfZGRzLCBub3JtYWxpemU9VFJVRSlbY29yX21pciRnZW5lW2ldLF0pLAogICAgICBtZXRob2Q9InNwZWFybWFuIiwKICAgICAgZXhhY3QgPSBGQUxTRSkKICBjb3JfbWlyJHJbaV0gPC0gYyRlc3RpbWF0ZQogIGNvcl9taXIkcHZhbHVlW2ldIDwtIGMkcC52YWx1ZQp9CgojIFNhdmluZyBjb3JfbWlyIG9iamVjdCBpbnRvIFJEUyBiZWNhdXNlIG9mIGxvbmcgY29tcHV0aW5nIHRpbWUKc2F2ZVJEUyhjb3JfbWlyLCAib3V0cHV0cy9SRFMvY29yX21pci5yZHMiKQpgYGAKCmBgYHtyfQojIGJlc3QgY29ycmVsYXRpb25zCmNvcl9taXIgPC0gcmVhZFJEUygib3V0cHV0cy9SRFMvY29yX21pci5yZHMiKQpoZWFkKGRwbHlyOjphcnJhbmdlKGNvcl9taXIscikpCnRhaWwoZHBseXI6OmFycmFuZ2UoY29yX21pcixyKSkKYGBgCgojIEROQW0gLSBtUk5BCgpDcmVhdGluZyBhbiBETkEgbWV0aHlsYXRpb24gYW5kIG1STkEgdGFibGUuIEFzIGlucHV0IGZvciBETkFtIGEgZ3JhbmdlcyBvYmplY3Qgd2l0aCBjcGcgaXNsYW5kIGludGVydmFscyBhbmQgYSBjb2x1bW4gdGhhdCBjb250YWlucyBnZW5lIG5hbWVzIHdob3NlIHByb21vdGVyIHJlZ2lvbiBvdmVybGFwcyB0aGF0IGNwZyBpc2xhbmQuCgpgYGB7cn0KbVJOQV9yZXNfc3ViIDwtIGRwbHlyOjpmaWx0ZXIoYXMuZGF0YS5mcmFtZShtUk5BX3JlcyksIHBhZGogPCAwLjA1KQoKdGFyZ19kbmFtX21STkEgPC0gCiAgcGx5cmFuZ2VzOjpmaWx0ZXIoZG5hbV9yZXNfY2dpLCBlbnNlbWJsICVpbiUgcm93bmFtZXMobVJOQV9yZXNfc3ViKSkKCnRhcmdfZG5hbV9tUk5BIDwtIHNhdmVSRFModGFyZ19kbmFtX21STkEsICJvdXRwdXRzL1JEUy90YXJnX2RuYW1fbVJOQS5yZHMiKQpgYGAKU29tZSBvZiB0aGUgY3BnICgxOSkgaXNsYW5kcyBvdmVybGFwIG1vcmUgdGhhbiBvbmUgZ2VuZSBwcm9tb3RlciwgYW5kIDcyIGdlbmVzIGhhdmUgMiAoZXhhY3RseSkgY3BnIGlzbGFuZHMgaW4gdGhlaXIgcHJvbW90ZXJzLgoKR1NFQSBHU0VBIGFuYWx5c2lzIG9uIGdlbmVzIHRoYXQgYXJlIHVuZGVyIG1ldGh5bGF0aW9uIHJlZ3VsYXRpb24uIFRoZXJlIG1hbnkgdGVybXMgZnJvbSBURiBzb3VyY2Ugd2hpY2ggaXMgZXhwZWN0ZWQuIFNpbmNlIHRoZSBkaWZmZXJlbnRpYWxseSBtZXRoeWxhdGVkIGNwZyBpc2xhbmRzIHRoYXQgd2VyZSBzZWxlY3RlZCBhcmUgaW4gcHJvbW90ZXIgcmVnaW9ucyBvZiB0aG9zZSBnZW5lcy4gQWxzbyBpbiBmcm9tIHRoZSByZWFjdG9tIGRhdGFiYXNlIHRoZXJlIGFyZSBtYW55IHRlcm1zIGludm9sdmVkIGluIHRoZSByZWd1bGF0aW9uIG9mIHRoZSBjZWxsIGN5Y2xlLgoKYGBge3J9CiMgVXNpbmcgb25seSBwYXJ0IG9mIHNvdXJjZXMKR1NFQV9TT1VSQ0VTIDwtIGMoIkdPOkJQIiwiQ09SVU0iLCJLRUdHIiwiUkVBQyIsIldQIiwiTUlSTkEiLCAiVEYiKQoKIyBDYWxsaW5nIGdvc3QgZnVuY3Rpb24KZ29zdF9yZXMgPC0gCiAgICBnb3N0KHRhcmdfZG5hbV9tUk5BJGVuc2VtYmwsCiAgICAgICBvcmdhbmlzbT0gImhzYXBpZW5zIiwKICAgICAgIGV4Y2x1ZGVfaWVhPVRSVUUsCiAgICAgICBkb21haW5fc2NvcGU9ImFubm90YXRlZCIsCiAgICAgICBvcmRlcmVkX3F1ZXJ5PUYsCiAgICAgICBzb3VyY2VzPUdTRUFfU09VUkNFUykKCiMgQ2hhbmdlIHF1ZXJ5IG5hbWUKZ29zdF9yZXMkcmVzdWx0JHF1ZXJ5IDwtICJERSBnZW5lcyB3aXRoIERNIHByb21vdGVycyIKCmdvc3RwbG90KGdvc3RfcmVzLCBjYXBwZWQgPSBGQUxTRSkKYGBgCgoKIyBTZXNzaW9uIEluZm8KYGBge3IgU2Vzc2lvbiBpbmZvfQpzZXNzaW9uSW5mbygpCmBgYAo=